// 2020.7.8 22:29

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <math.h>

void input_line(const char *dst, int n)
{
    char * s = (char*) dst;
    int cnt = 0;
    char ch;
    ch = getchar();
    while (ch != '\n' && cnt < n)
    {
        *s = ch;
        ++s;
        ++cnt;
        ch = getchar();
    }
    if (cnt == n && *s != '\n')
    {
        s--;
        *s = '\0';
        while (ch != '\n') ch = getchar();
    }
    else {
        *s = '\0';
    }
}

void trim(char* strIn, char* strOut) 
{
    char *a=strIn, *b;                              // # support in-place opreation
    while (*a == ' '||*a == '\n' ||*a == '\t') a++; // ignore spaces at the beginning
    b = strIn + strlen(strIn) - 1;                  // get pointer pointing at the end of the line
    while (*b == ' '||*b == '\n' ||*a == '\t') b--; // ignore spaces at the end
    while (a <= b) *strOut++ = *a++;                // transplace
    *strOut='\0';
}

int get_int_input()
{
    char input[32];
    input_line(input, 32);
    trim(input,input);
    if (input[0] >= '0' && input[0] <= '9'){
        return atoi(input);
    }
    else if ((input[0] == '-' || input[0] == '+') && input[1] >= '0' && input[1] <= '9'){
        return atoi(input);
    }
    else {
        printf("Illegal input! Try again.\n");
        return get_int_input();
    }
}

int get_int_choice(int range_a, int range_b)
{
    int choice = get_int_input();
    while (choice > range_b || choice < range_a)
    {
        printf("Choice doesn't exist.\n");
        choice = get_int_input();
    }
    return choice;
}

char input[32];
struct date
{
    int year;
    int month;
    int day;
};


struct student
{
    char id[16]; 
    char name[32];
    char gender[16];
    int score[3];
    char tel[16];
    //date birth;
};
student students[128];
int tot_students = 0;

void view_student(student * st)
{
    int i =0;
    printf("%s %s %s %s ", 
        st->id,
        st->name,
        st->gender,
        st->tel
    );
    printf("%d %d %d",st->score[0],st->score[1],st->score[2]);
    printf("\n");
}

void view_students()
{
    for (int i = 0; i < tot_students; i++)
    {
        view_student(&students[i]);
    }
}

student* search_students()
{
    char keyword[32];
    printf("Input a keyword to search: ");
    input_line(keyword,32);
    printf("Search results:\n");
    int num = 0;
    student* results[128];
    for (int i = 0; i < tot_students; i++)
    {
        char* if_ID = strstr(students[i].id, keyword);
        char* if_name = strstr(students[i].name, keyword);
        if (if_ID || if_name){
            results[num] = & students[i];
            printf("%d. ",num + 1);
            view_student(& students[i]);
            num++;
        }
    }
    printf("Choose a results: ");
    int choice = 0;
    choice = get_int_choice(0,num);
    if (choice == 0) return NULL;
    else return results[choice-1];
}

void edit_student()
{
    printf("You're goint to edit a student: \n");
    student* st = search_students();
    printf("- Input something to replace previoius ones;\n");
    printf("- Type '#' or nothing to NOT modify certain items;\n");
    
    char input[128]; // store input

    printf("  Stu. ID: %16s | ", st->id);
    input_line(input,128); 
    trim(input, input);
    if (input[0] != '#' && input [0] != '\0') strcpy(st->id,input);

    printf("  Name   : %16s | ", st->name); 
    input_line(input,128); 
    trim(input, input);
    if (input[0] != '#' && input [0] != '\0') strcpy(st->name,input);

    printf("  Tel Num: %16s | ", st->tel); 
    input_line(input,128); 
    trim(input, input);
    if (input[0] != '#' && input [0] != '\0') strcpy(st->tel,input);

    printf("  Gender : %16s | ", st->gender); 
    input_line(input,128); 
    trim(input, input);
    if (input[0] != '#' && input [0] != '\0') strcpy(st->gender,input);
    
    for (int i = 0; i < 3; i++)
    {
        printf("  Score%d : %d | ", i+1, st->score[i]); 
        st->score[i] = get_int_input();
    }

    printf("# Student's information has been updated!\n");
}

void add_student()
{
    printf("You're goint to edit a student: \n");
    char input[128]; //set input buffer
    student * st = &students[tot_students];

    printf("%-16s | ", "Stu. ID", st->id);
    input_line(input,128); 
    trim(input, input);
    strcpy(st->id,input);

    printf("%-16s | ", "Name", st->name); 
    input_line(input,128); 
    trim(input, input);
    strcpy(st->name,input);

    printf("%-16s | ", "Tel Num", st->tel); 
    input_line(input,128); 
    trim(input, input);
    strcpy(st->tel,input);

    printf("%-16s | ", "Gender", st->gender); 
    input_line(input,128); 
    trim(input, input);
    strcpy(st->gender,input);
    
    for (int i = 0; i < 3; i++)
    {
        printf("%-14s%02d | ", "Score", i+1); 
        st->score[i] = get_int_input();
    }
    tot_students++;
    view_student(st);
}

void search_fail()
{
    printf("Search results:\n");
    int num = 0;
    for (int i = 0; i < tot_students; i++) {
        bool failed = false;
        for (int j = 0; j < 3; i++) {
            if (students[i].score[j] < 60) {
                failed = true;
                break;
            }
        }
        if (failed) {
            printf("%d. ", num + 1);
            view_student(&students[i]);
            num++;
        }
    }
}

void sort_students_by_score(int w = 0)
{
    student temp;
    for (int i = 0; i < tot_students - 1; i++)
    {
        for (int j = 0; j < tot_students - 1 - i; j++)
        {
            if (students[j].score[w] < students[j+1].score[w])
            {
                temp = students[j+1];
                students[j+1] = students[j];
                students[j] = temp;
            }
        }
    }
    view_students();
}

void del_student()
{
    printf("You're goint to delete a student: \n");
    student* st = search_students();
    int index = st - students;
    for (int i = index; i < tot_students - 1; i++)
    {
        students[i] = students[i+1];
    }
    tot_students--;
    printf("Student delete successfully!\n");
    view_students();
}

void menu()
{
    printf(" - 1. View all students;\n");
    printf(" - 2. Search a student;\n");
    printf(" - 3. Edit a student;\n");
    printf(" - 4. View failed student;\n");
    printf(" - 5. Sort by a course's score;\n");
    printf(" - 6. Add a student;\n");
    printf(" - 7. Delete a student;\n");
    printf(" - 0. Exit.\n");
}

int main()
{
    int run = 1;
    while (run)
    {
        menu();
        int choice = get_int_choice(0,7);
        switch(choice)
        {
            case 1: view_students(); break;
            case 2: search_students(); break;
            case 3: edit_student(); break;
            case 4: search_fail(); break;
            case 5: sort_students_by_score(get_int_choice(1,3)-1); break;
            case 6: add_student(); break;
            case 7: del_student(); break;
            case 0: run = 0; break;
        }
    }
    return 0;
}